use criterion::{Criterion, criterion_group, criterion_main};
use regex::RegexBuilder;

const HAYSTACK: &str = "This is a huge huge huge HAYSTACK.";

const HAYSTACK_LOWER: &str = "This is a huge huge huge haystack.";
const NEEDLE: &str = "haystack";

fn filter_benchmark_std(c: &mut Criterion) {
    c.bench_function("find needle by std normal", |b| b.iter(|| {
        assert!(!HAYSTACK.contains(NEEDLE));
    }));
    c.bench_function("find needle by std ignore case", |b| b.iter(|| {
        assert!(HAYSTACK_LOWER.contains(NEEDLE.to_lowercase().as_str()));
    }));
}

fn filter_benchmark_regex(c: &mut Criterion) {
    let regex1 = RegexBuilder::new(NEEDLE).build().unwrap();
    c.bench_function("find needle by regex", |b| b.iter(|| {
        assert!(!regex1.find(HAYSTACK).is_some());
    }));
    let regex2 = RegexBuilder::new(NEEDLE).case_insensitive(true).build().unwrap();
    c.bench_function("find needle by regex ignore case", |b| b.iter(|| {
        assert!(regex2.find(HAYSTACK).is_some());
    }));
}

fn filter_benchmark_memchr(c: &mut Criterion) {
    c.bench_function("find needle by memchr", |b| b.iter(|| {
        assert!(!memchr::memmem::find(HAYSTACK.as_bytes(), NEEDLE.as_bytes()).is_some())
    }));
    c.bench_function("find needle by memchr ignore case", |b| b.iter(|| {
        assert!(memchr::memmem::find(HAYSTACK.to_lowercase().as_bytes(), NEEDLE.to_lowercase().as_bytes()).is_some())
    }));
}

criterion_group!(benches, filter_benchmark_std, filter_benchmark_regex, filter_benchmark_memchr);
criterion_main!(benches);
